// reviewScheduler.js - 单词复习计划管理
// 提供单例模式的复习计划管理器
let instance = null;

/**
 * 记忆魔法屋 - 复习计划管理器
 * 根据艾宾浩斯记忆曲线原理实现单词复习计划
 */
class ReviewScheduler {
  constructor() {
    // 艾宾浩斯复习间隔（分钟）
    this.reviewIntervals = [1, 5, 30, 120, 360, 1440, 2880, 4320]; // 1分钟, 5分钟, 30分钟, 2小时, 6小时, 1天, 2天, 3天
    // 单词记忆难度系数影响复习间隔的调整
    this.difficultyFactors = {
      easy: 0.8,    // 容易的单词复习间隔延长20%
      normal: 1.0,  // 正常难度保持原间隔
      hard: 1.5     // 难的单词复习间隔缩短40%
    };
  }

  /**
   * 获取复习计划管理器的单例实例
   * @returns {ReviewScheduler} 复习计划管理器实例
   */
  static getInstance() {
    if (!instance) {
      instance = new ReviewScheduler();
    }
    return instance;
  }

  /**
   * 初始化复习计划管理器
   * @param {WordLearningDataManager} wordLearningDataManager - 单词学习数据管理器实例
   * @param {WordDataManager} wordDataManager - 单词数据管理器实例
   */
  initialize(wordLearningDataManager, wordDataManager) {
    this.wordLearningDataManager = wordLearningDataManager;
    this.wordDataManager = wordDataManager;
  }

  /**
   * 获取所有需要复习的单词
   * @param {string} bookId - 可选，特定词书ID
   * @returns {Array} 需要复习的单词列表
   */
  getWordsForReview(bookId = null) {
    let allWords = [];
    
    try {
      if (bookId) {
        // 获取特定词书的单词
        allWords = this.wordDataManager.getWordsByBookId(bookId);
      } else {
        // 获取所有单词
        const wordsDict = this.wordDataManager.getAllWords();
        allWords = Object.values(wordsDict);
      }
      
      const now = new Date().getTime();
      const wordsForReview = allWords.filter(word => {
        const wordId = word.id;
        // 只考虑已经学习过的单词（learnCount > 0）
        const learnCount = this.wordDataManager.getWordLearnCount(wordId);
        if (learnCount <= 0) {
          return false;
        }
        
        // 已经记住的单词暂时不需要复习
        const isMemorized = this.wordDataManager.getWordMemorizedStatus(wordId);
        if (isMemorized) {
          return false;
        }
        
        // 计算下次复习时间
        const lastLearnTime = this.wordDataManager.getWordLastLearnTime(wordId);
        const lastLearnTimeMs = lastLearnTime ? new Date(lastLearnTime).getTime() : now;
        const difficulty = this._getWordDifficulty(word);
        
        // 根据学习次数和难度确定复习间隔
        const intervalIndex = Math.min(learnCount - 1, this.reviewIntervals.length - 1);
        const baseInterval = this.reviewIntervals[intervalIndex] * 60 * 1000; // 转换为毫秒
        const adjustedInterval = baseInterval / this.difficultyFactors[difficulty];
        
        // 检查是否到了复习时间
        const nextReviewTime = lastLearnTimeMs + adjustedInterval;
        return now >= nextReviewTime;
      });
      
      // 按优先级排序：最需要复习的单词排在前面
      const sortedWords = wordsForReview.sort((a, b) => {
        const aPriority = this._getReviewPriority(a);
        const bPriority = this._getReviewPriority(b);
        return bPriority - aPriority;
      });
      
      return sortedWords;
    } catch (error) {
      console.error('获取复习单词失败:', error);
      return [];
    }
  }

  /**
   * 获取单词的复习优先级
   * @private
   * @param {Object} word - 单词对象
   * @returns {number} 优先级分数，越高越需要复习
   */
  _getReviewPriority(word) {
    const wordId = word.id;
    const now = new Date().getTime();
    const lastLearnTime = this.wordDataManager.getWordLastLearnTime(wordId);
    const lastLearnTimeMs = lastLearnTime ? new Date(lastLearnTime).getTime() : now;
    const learnCount = this.wordDataManager.getWordLearnCount(wordId) || 1;
    const difficulty = this._getWordDifficulty(word);
    
    // 计算应该复习的时间点
    const intervalIndex = Math.min(learnCount - 1, this.reviewIntervals.length - 1);
    const baseInterval = this.reviewIntervals[intervalIndex] * 60 * 1000;
    const adjustedInterval = baseInterval / this.difficultyFactors[difficulty];
    const nextReviewTime = lastLearnTimeMs + adjustedInterval;
    
    // 计算逾期时间（毫秒）
    const overdueTime = Math.max(0, now - nextReviewTime);
    
    // 优先级计算：逾期时间越长、学习次数越少、难度越高，优先级越高
    let priority = overdueTime / (24 * 60 * 60 * 1000); // 转换为天
    
    if (learnCount <= 3) {
      priority *= 2; // 新学的单词优先级更高
    }
    
    if (difficulty === 'hard') {
      priority *= 1.5; // 难的单词优先级更高
    }
    
    return priority;
  }

  /**
   * 获取单词的难度评估
   * @private
   * @param {Object} word - 单词对象
   * @returns {string} 难度级别：easy, normal, hard
   */
  _getWordDifficulty(word) {
    // 这里可以实现更复杂的难度评估算法
    // 当前实现：基于学习次数和是否标记为难词
    const wordId = word.id;
    const learnCount = this.wordDataManager.getWordLearnCount(wordId) || 1;
    const isHardWord = word.tags && word.tags.includes('hard');
    
    if (isHardWord || learnCount > 5) {
      return 'hard';
    } else if (learnCount <= 2) {
      return 'normal';
    } else {
      return 'easy';
    }
  }

  /**
   * 获取待复习单词的数量
   * @param {string} bookId - 可选，特定词书ID
   * @returns {number} 待复习单词数量
   */
  getReviewCount(bookId = null) {
    return this.getWordsForReview(bookId).length;
  }

  /**
   * 记录单词复习结果
   * @param {string} wordId - 单词ID
   * @param {boolean} isRemembered - 是否记住
   * @param {string} difficulty - 难度评级 (easy, normal, hard)
   */
  recordReviewResult(wordId, isRemembered, difficulty = 'normal') {
    try {
      // 获取单词
      const word = this.wordDataManager.getWordById(wordId);
      if (!word) {
        console.error(`单词 ${wordId} 不存在`);
        return;
      }
      
      // 获取当前学习数据
      let learningData = this.wordLearningDataManager.getLearningData(wordId);
      
      // 初始化学习数据（如果不存在）
      if (!learningData) {
        learningData = {
          learnCount: 0,
          lastLearnTime: new Date().toISOString(),
          memorized: false,
          reviewHistory: []
        };
      } else if (!Array.isArray(learningData.reviewHistory)) {
        // 确保 reviewHistory 是一个数组
        learningData.reviewHistory = [];
      }
      
      // 记录复习历史
      learningData.reviewHistory.push({
        time: new Date().toISOString(),
        isRemembered,
        difficulty
      });
      
      // 更新学习次数
      if (isRemembered) {
        learningData.learnCount += 1;
        // 如果连续记住多次，可以标记为已记忆
        const recentSuccesses = learningData.reviewHistory
          .slice(-3) // 最近3次复习
          .filter(record => record.isRemembered).length;
        
        if (recentSuccesses >= 3 && learningData.learnCount >= 5) {
          learningData.memorized = true;
        }
      }
      
      // 更新最近学习时间
      learningData.lastLearnTime = new Date().toISOString();
      
      // 保存更新后的学习数据
      this.wordLearningDataManager.updateLearningData(wordId, learningData);
    } catch (error) {
      console.error('记录复习结果失败:', error);
    }
  }

  /**
   * 生成每日复习计划
   * @returns {Object} 每日复习计划
   */
  generateDailyReviewPlan() {
    try {
      const wordsForReview = this.getWordsForReview();
      const totalCount = wordsForReview.length;
      
      // 根据单词数量和难度分配复习时间
      let suggestedTime = 0;
      if (totalCount <= 10) {
        suggestedTime = 5;
      } else if (totalCount <= 20) {
        suggestedTime = 10;
      } else if (totalCount <= 40) {
        suggestedTime = 15;
      } else {
        suggestedTime = 20;
      }
      
      // 按难度分组
      const easyWords = wordsForReview.filter(word => this._getWordDifficulty(word) === 'easy');
      const normalWords = wordsForReview.filter(word => this._getWordDifficulty(word) === 'normal');
      const hardWords = wordsForReview.filter(word => this._getWordDifficulty(word) === 'hard');
      
      // 添加记忆魔法屋特有数据
      const plan = {
        totalCount,
        suggestedTime,
        breakdown: {
          easy: easyWords.length,
          normal: normalWords.length,
          hard: hardWords.length
        },
        words: wordsForReview.slice(0, 20), // 返回前20个最需要复习的单词
        // 添加一些记忆魔法屋特有的信息
        magicPower: this._calculateMagicPower(wordsForReview),
        completionBonus: this._calculateCompletionBonus(totalCount)
      };
      
      return plan;
    } catch (error) {
      console.error('生成每日复习计划失败:', error);
      // 发生错误时返回空计划
      return {
        totalCount: 0,
        suggestedTime: 0,
        breakdown: {
          easy: 0,
          normal: 0,
          hard: 0
        },
        words: [],
        magicPower: 0,
        completionBonus: 0
      };
    }
  }
  
  /**
   * 计算当前复习计划的魔法能量
   * @private
   * @param {Array} wordsForReview - 待复习单词列表
   * @returns {number} 魔法能量值
   */
  _calculateMagicPower(wordsForReview) {
    // 根据单词数量、难度和逾期情况计算魔法能量
    let power = 0;
    wordsForReview.forEach(word => {
      const difficulty = this._getWordDifficulty(word);
      const priority = this._getReviewPriority(word);
      
      if (difficulty === 'hard') {
        power += 10;
      } else if (difficulty === 'normal') {
        power += 5;
      } else {
        power += 2;
      }
      
      // 逾期时间越长，魔法能量越高
      if (priority > 1) {
        power += Math.min(priority * 2, 10);
      }
    });
    
    return Math.min(power, 100); // 限制在100以内
  }
  
  /**
   * 计算完成复习计划的奖励
   * @private
   * @param {number} totalCount - 总单词数
   * @returns {number} 奖励值
   */
  _calculateCompletionBonus(totalCount) {
    // 简单的奖励计算逻辑：单词越多奖励越高
    return Math.min(totalCount * 2, 50);
  }
}

module.exports = {
  ReviewScheduler,
  getInstance: ReviewScheduler.getInstance
};

// 同时设置默认导出为单例实例
module.exports.default = ReviewScheduler.getInstance();
